package com.trinity.face

import android.content.Context
import com.alibaba.android.mnnkit.actor.FaceDetector
import com.alibaba.android.mnnkit.entity.FaceDetectConfig
import com.alibaba.android.mnnkit.entity.MNNCVImageFormat
import com.alibaba.android.mnnkit.entity.MNNFlipType
import com.alibaba.android.mnnkit.intf.InstanceCreatedListener
import com.alibaba.android.mnnkit.monitor.MNNMonitor
import com.tool.Log
import com.tool.WkLogTool

class MnnFaceDetection : FaceDetection {

  private var mFaceDetector: FaceDetector ?= null
  //private val mFaceDetectionReports = Array(20) { FaceDetectionReport() }

  override fun createFaceDetection(context: Context, type: Int): Int {
    // 默认情况下，MNNKit会收集SDK运行时的性能、稳定性等数据，帮助我们统计和分析问题。这里关掉它。
    MNNMonitor.setMonitorEnable(false)
    // 配置参数，可用来配置是视频检测还是图片检测
    val config = FaceDetector.FaceDetectorCreateConfig()
    config.mode = if (type == 0) FaceDetector.FaceDetectMode.MOBILE_DETECT_MODE_VIDEO else FaceDetector.FaceDetectMode.MOBILE_DETECT_MODE_IMAGE

    // 异步创建FaceDetector实例
    FaceDetector.createInstanceAsync( context, config, object: InstanceCreatedListener<FaceDetector> {
      override fun onFailed(p0: Int, error: Error?) {
        Log.e("trinity", "人脸识别实例创建失败 ，error: ${error?.message}")
      }

      override fun onSucceeded(faceDetector: FaceDetector?) {
        mFaceDetector = faceDetector
      }

    })
    return 0
  }

  override fun faceDetection(data: ByteArray, width: Int, height: Int,
                             inAngle: Int, outAngle: Int, flipType: MNNFlipType): Array<FaceDetectionReport> {

    val outputFlip = flipType ;
    // 关注一下几个动作：眨眼、张嘴、上下摇头、左右摇头、挑眉
    val detectConfig = FaceDetectConfig.ACTIONTYPE_EYE_BLINK or FaceDetectConfig.ACTIONTYPE_MOUTH_AH or FaceDetectConfig.ACTIONTYPE_HEAD_YAW or FaceDetectConfig.ACTIONTYPE_HEAD_PITCH or FaceDetectConfig.ACTIONTYPE_BROW_JUMP
    val result = mFaceDetector?.inference(data, width, height, MNNCVImageFormat.YUV_NV21, detectConfig, inAngle, outAngle, outputFlip)

    val size = result?.size ?: 0

    val faceDetectionReports = Array(size) {
      FaceDetectionReport()
    }

    if (size >= 20) {
      WkLogTool.showMsg("检测到人脸数目超过20个。不支持这么多。")
    } else {
      result?.forEachIndexed { index, faceDetectionReport ->
        val faceDetection = faceDetectionReports[index]
        // rect 代表面部的矩形区域
        faceDetectionReport.rect?.let {
          faceDetection.left = it.left
          faceDetection.right = it.right
          faceDetection.top = it.top
          faceDetection.bottom = it.bottom
        }

        // 每个检测到的人脸拥有唯一的faceID.人脸跟踪丢失以后重新被检测到,会有一个新的faceID.
        faceDetection.faceId = faceDetectionReport.faceID
        // 人脸106关键点的数组，依次为特征点1的坐标（X1, Y1），特征点2（X2, Y2）...
        faceDetection.keyPoints = faceDetectionReport.keyPoints
        // 对应点的能见度,点未被遮挡1.0,被遮挡0.0
        faceDetection.visibilities = faceDetectionReport.visibilities
        // 置信度
        faceDetection.score = faceDetectionReport.score
        // 水平转角,真实度量的左负右正
        faceDetection.yaw = faceDetectionReport.yaw
        //  俯仰角,真实度量的上负下正
        faceDetection.pitch = faceDetectionReport.pitch
        // 旋转角,真实度量的左负右正
        faceDetection.roll = faceDetectionReport.roll
        // 脸部动作
        faceDetection.faceAction = faceDetectionReport.faceAction
        //  脸部动作Map
        faceDetection.faceActionMap = faceDetectionReport.faceActionMap
        faceDetectionReports[index] = faceDetection
      }
    }
    return faceDetectionReports
  }

  override fun releaseDetection() {
    mFaceDetector?.release()
  }
}